{
 "cells": [
  {
   "cell_type": "raw",
   "id": "7fb2a67a",
   "metadata": {},
   "source": [
    "---\n",
    "sidebar_position: 2\n",
    "---"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3c284df8",
   "metadata": {},
   "source": [
    "# XML Agent\n",
    "\n",
    "Some language models (like Anthropic's Claude) are particularly good at reasoning/writing XML. This goes over how to use an agent that uses XML when prompting. \n",
    "\n",
    ":::tip\n",
    "\n",
    "* Use with regular LLMs, not with chat models.\n",
    "* Use only with unstructured tools; i.e., tools that accept a single string input.\n",
    "* See [AgentTypes](/docs/modules/agents/agent_types/) documentation for more agent types.\n",
    ":::"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "a1f30fa5",
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain import hub\n",
    "from langchain.agents import AgentExecutor, create_xml_agent\n",
    "from langchain_community.chat_models import ChatAnthropic\n",
    "from langchain_community.tools.tavily_search import TavilySearchResults"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fe972808",
   "metadata": {},
   "source": [
    "## Initialize Tools\n",
    "\n",
    "We will initialize the tools we want to use"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "e30e99e2",
   "metadata": {},
   "outputs": [],
   "source": [
    "tools = [TavilySearchResults(max_results=1)]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6b300d66",
   "metadata": {},
   "source": [
    "## Create Agent"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "08a63869",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Get the prompt to use - you can modify this!\n",
    "prompt = hub.pull(\"hwchase17/xml-agent-convo\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "5490f4cb",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Choose the LLM that will drive the agent\n",
    "llm = ChatAnthropic(model=\"claude-2\")\n",
    "\n",
    "# Construct the XML agent\n",
    "agent = create_xml_agent(llm, tools, prompt)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "03c26d04",
   "metadata": {},
   "source": [
    "## Run Agent"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "8e39b42a",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Create an agent executor by passing in the agent and tools\n",
    "agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "00d768aa",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n",
      "\u001b[32;1m\u001b[1;3m <tool>tavily_search_results_json</tool><tool_input>what is LangChain?\u001b[0m\u001b[36;1m\u001b[1;3m[{'url': 'https://aws.amazon.com/what-is/langchain/', 'content': 'What Is LangChain? What is LangChain?  How does LangChain work?  Why is LangChain important?  that LangChain provides to reduce development time.LangChain is an open source framework for building applications based on large language models (LLMs). LLMs are large deep-learning models pre-trained on large amounts of data that can generate responses to user queries—for example, answering questions or creating images from text-based prompts.'}]\u001b[0m\u001b[32;1m\u001b[1;3m <final_answer>LangChain is an open source framework for building applications based on large language models (LLMs). It allows developers to leverage the power of LLMs to create applications that can generate responses to user queries, such as answering questions or creating images from text prompts. Key benefits of LangChain are reducing development time and effort compared to building custom LLMs from scratch.</final_answer>\u001b[0m\n",
      "\n",
      "\u001b[1m> Finished chain.\u001b[0m\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "{'input': 'what is LangChain?',\n",
       " 'output': 'LangChain is an open source framework for building applications based on large language models (LLMs). It allows developers to leverage the power of LLMs to create applications that can generate responses to user queries, such as answering questions or creating images from text prompts. Key benefits of LangChain are reducing development time and effort compared to building custom LLMs from scratch.'}"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "agent_executor.invoke({\"input\": \"what is LangChain?\"})"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3dbdfa1d",
   "metadata": {},
   "source": [
    "## Using with chat history"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "cca87246",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n",
      "\u001b[32;1m\u001b[1;3m <final_answer>Your name is Bob.</final_answer>\n",
      "\n",
      "Since you already told me your name is Bob, I do not need to use any tools to answer the question \"what's my name?\". I can provide the final answer directly that your name is Bob.\u001b[0m\n",
      "\n",
      "\u001b[1m> Finished chain.\u001b[0m\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "{'input': \"what's my name? Only use a tool if needed, otherwise respond with Final Answer\",\n",
       " 'chat_history': 'Human: Hi! My name is Bob\\nAI: Hello Bob! Nice to meet you',\n",
       " 'output': 'Your name is Bob.'}"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from langchain_core.messages import AIMessage, HumanMessage\n",
    "\n",
    "agent_executor.invoke(\n",
    "    {\n",
    "        \"input\": \"what's my name? Only use a tool if needed, otherwise respond with Final Answer\",\n",
    "        # Notice that chat_history is a string, since this prompt is aimed at LLMs, not chat models\n",
    "        \"chat_history\": \"Human: Hi! My name is Bob\\nAI: Hello Bob! Nice to meet you\",\n",
    "    }\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "53ad1a2c",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
